home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Windows Expert
/
Windows Expert.iso
/
windownt
/
mdipad.zip
/
TOOLBAR.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-02-24
|
36KB
|
1,122 lines
// ************************************************************************
// MODULE : ToolBar.C
// PURPOSE :
// FUNCTIONS :
// ************************************************************************
#define NOCREATEFONT
#ifdef DEBUG
#define DebugOut( str ) OutputDebugString ( (LPCTSTR) __FILE__ TEXT( ": " ) TEXT( str ) TEXT( "\n" ) )
#else
#define DebugOut( str )
#endif
#ifndef WIN32
#define INT int
#endif
#ifndef WIN32S
#define UNICODE // make the application unicode complient
#endif
#define STRICT
#include <windows.h>
#include <stdlib.h> // For 'abs'
#ifdef WIN32
#define GetWindowInstance(hwnd) (HANDLE) GetWindowLong( hwnd, GWL_HINSTANCE )
#define GetWindowID(hwnd) GetWindowLong( hwnd, GWL_ID )
#else
#define GetWindowInstance(hwnd) (HANDLE) GetWindowWord( hwnd, GWW_HINSTANCE )
#define GetWindowID(hwnd) GetWindowWord( hwnd, GWW_ID )
#endif
HWND hwndMain;
HWND hwndTools, hwndToolText, hwndToolCombo, hwndToolButton;
HWND hwndStatus;
HFONT hfontTools=0;
HFONT hfontStatus;
TEXTMETRIC tmToolFont;
TEXTMETRIC tmStatusFont;
INT dyTools = 0, dyCombo;
INT cxToolBorder, cyToolBorder, cntToolCtrls = 0;
INT xCurrent = 10;
INT dxTools;
INT cntStatusField = 0;
INT dyStatus, cxStatusBorder, cyStatusBorder, cxFrame, cyFrame, dyField;
HBRUSH hbrBtnFace=0;
HBRUSH hbrToolBar=0;
HBRUSH hbrStatus=0;
// HANDLE hInst=0;
#define COLOR_BLACK RGB(0, 0, 0)
#define COLOR_WHITE RGB(255, 255, 255)
#define COLOR_HEAVYGRAY RGB(64, 64, 64)
#define COLOR_DARKGRAY RGB(128, 128, 128)
#define COLOR_GRAY RGB(192, 192, 192)
COLORREF rgbFrame = COLOR_BLACK;
COLORREF rgbBtnFace = COLOR_GRAY;
COLORREF rgbHilite = COLOR_WHITE;
COLORREF rgbDirectLight = COLOR_WHITE;
COLORREF rgbShadow = COLOR_DARKGRAY;
COLORREF rgbToolBar = COLOR_GRAY;
COLORREF rgbStatic = COLOR_BLACK;
#define TC_SPACE 0
#define TC_LABEL 1
#define TC_COMBO 2
#define TC_BUTTON 3
#define MAXCTRLS 25
typedef struct _tagTools {
HWND hwnd;
WORD wType;
INT iWidth, iHeight;
HICON hIcon;
} Tools;
Tools toolCtrl[MAXCTRLS];
#define MAXSTATUS 10
typedef struct _tagStatus {
HWND hwnd;
INT iMaxWidth, iMinWidth, iGiveWidth;
} Status;
Status statusField[ MAXSTATUS ];
//-- internal prototypes
LONG CALLBACK ToolsProc (HWND, UINT, WPARAM, LPARAM);
LONG CALLBACK MyComboProc (HWND, UINT, WPARAM, LPARAM);
VOID UpdatePositions (HWND);
LONG CALLBACK StatusProc (HWND, UINT, WPARAM, LPARAM);
LONG CALLBACK StatusFieldProc (HWND, UINT, WPARAM, LPARAM);
// ************************************************************************
// FUNCTION : DllEntryPoint( HINSTANCE, DWORD, LPVOID )
// PURPOSE : DllEntryPoint is called by Windows when
// the DLL is initialized, Thread Attached, and other times.
// COMMENTS : No initialization is needed here.
// ************************************************************************
BOOL WINAPI
DllEntryPoint( HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpvReserved )
{
UNREFERENCED_PARAMETER( hInstDLL );
UNREFERENCED_PARAMETER( fdwReason );
UNREFERENCED_PARAMETER( lpvReserved );
return( TRUE );
}
// ========================================================================
// TOOL BAR FUNCTIONS
// ========================================================================
// ************************************************************************
// FUNCTION : InitToolBar (HANDLE hInstance)
// PURPOSE :
// COMMENTS :
// ************************************************************************
BOOL
InitToolBar (HANDLE hInstance)
{
WNDCLASS wndclass;
hbrBtnFace = CreateSolidBrush( rgbBtnFace );
hbrToolBar = CreateSolidBrush( rgbToolBar );
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = (WNDPROC) ToolsProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = NULL;
wndclass.hbrBackground = hbrToolBar;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = TEXT( "ToolBar" );
if( !RegisterClass(&wndclass) )
return FALSE;
}
// ************************************************************************
// FUNCTION : CreateToolBar( HWND hwnd, HANDLE hInstance, INT iId )
// PURPOSE :
// COMMENTS :
// ************************************************************************
BOOL
CreateToolBar( HWND hwnd, HANDLE hInstance, INT iId )
{
HWND hwndTmp;
RECT rect;
DebugOut( "CreateToolBar" );
if( hbrBtnFace==0 )
hbrBtnFace = CreateSolidBrush( rgbBtnFace );
if( hbrToolBar==0 )
hbrToolBar = CreateSolidBrush( rgbToolBar );
cxToolBorder = GetSystemMetrics( SM_CXBORDER );
cyToolBorder = GetSystemMetrics( SM_CYBORDER );
DebugOut( "Calling CreateWindow" );
hwndTools = CreateWindow ( TEXT( "ToolBar" ), TEXT( "ToolBar" ),
WS_CHILD | WS_CLIPSIBLINGS | WS_BORDER | WS_VISIBLE,
0, 0, 0, 0,
hwnd, (HMENU) iId, hInstance, NULL );
if( !hwndTools ) {
DebugOut( "CreateWindow Failed" );
return FALSE;
}
DebugOut( "CreateWindow suceeded" );
/* Lets find out how big a combo box is... */
hwndTmp = CreateWindow ( TEXT( "COMBOBOX" ), TEXT( "Combo" ),
WS_CHILD //| WS_CLIPSIBLINGS
| WS_VISIBLE | CBS_DROPDOWNLIST,
0, 0, 0, 0,
hwndTools, NULL, hInstance, NULL);
if( hwndTmp ) {
// SendMessage( hwndTmp, WM_SETFONT, (UINT) hfontTools, MAKELONG (TRUE, 0) );
GetClientRect( hwndTmp, &rect );
dyCombo = rect.bottom - rect.top;
DestroyWindow( hwndTmp );
}
else {
dyCombo = 30; // Just for a default value
}
hwndMain = hwnd; // So we can pass WM_CONTROL messages back to the master parent
hInstance; // unreferenced
return TRUE;
}
// ************************************************************************
// FUNCTION : ToolBarHeight( HWND hwnd )
// PURPOSE :
// COMMENTS :
// ************************************************************************
int
ToolBarHeight( HWND hwnd )
{
RECT rect;
GetClientRect( hwndTools, &rect );
return( rect.bottom-rect.top );
hwnd; // unreferenced
}
// ************************************************************************
// FUNCTION : AdjustToolBar( HWND hwnd )
// PURPOSE :
// COMMENTS :
// ************************************************************************
BOOL
AdjustToolBar( HWND hwnd )
{
RECT rect;
GetClientRect (hwnd, &rect);
MoveWindow( hwndTools,
rect.left - cxToolBorder,
rect.top - cyToolBorder,
rect.right - rect.left + (cxToolBorder*2),
dyTools,
TRUE );
return TRUE;
}
// ************************************************************************
// FUNCTION : UpdatePositions( HWND hwnd )
// PURPOSE :
// COMMENTS :
// ************************************************************************
VOID
UpdatePositions( HWND hwnd )
{
INT i, x, y, dx, dy, cnt;
x = 10;
for( i=0; i<cntToolCtrls; i++ ) {
switch( toolCtrl[i].wType ) {
case TC_SPACE:
dx = toolCtrl[i].iWidth;
break;
case TC_LABEL:
dy = toolCtrl[i].iHeight;
y = (dyTools/2) - (dy/2) - 1;
dx = toolCtrl[i].iWidth;
break;
case TC_COMBO:
dy = toolCtrl[i].iHeight;
y = (dyTools/2) - (dy/2) - 1;
dx = toolCtrl[i].iWidth;
cnt = (INT) SendMessage( toolCtrl[i].hwnd, CB_GETCOUNT,
(WPARAM) 0, (LPARAM) 0 );
if( cnt > 5 )
cnt = 5;
dy = dy * cnt;
break;
case TC_BUTTON:
dy = toolCtrl[i].iHeight;
y = (dyTools/2) - (dy/2) - 1;
dx = toolCtrl[i].iWidth;
break;
default:
dy = toolCtrl[i].iHeight;
y = (dyTools/2) - (dy/2) - 1;
dx = toolCtrl[i].iWidth;
break;
}
if( toolCtrl[i].wType != TC_SPACE ) {
MoveWindow( toolCtrl[i].hwnd, x, y, dx, dy, FALSE );
}
x += dx;
}
if( hwnd == NULL ) {
UpdateWindow( hwndTools );
}
else{
UpdateWindow( hwnd );
}
}
// ************************************************************************
// FUNCTION : AddToolSpace( INT iWidth, INT iHeight )
// PURPOSE :
// COMMENTS :
// ************************************************************************
BOOL
AddToolSpace( INT iWidth, INT iHeight )
{
if( cntToolCtrls >= MAXCTRLS )
return FALSE;
toolCtrl[cntToolCtrls].hwnd = 0;
toolCtrl[cntToolCtrls].wType = TC_SPACE;
toolCtrl[cntToolCtrls].iWidth = iWidth;
toolCtrl[cntToolCtrls].iHeight = iHeight;
if( (toolCtrl[cntToolCtrls].iHeight + (6*cyToolBorder)) > dyTools ) {
dyTools = (toolCtrl[cntToolCtrls].iHeight + (6*cyToolBorder));
}
UpdatePositions( NULL );
cntToolCtrls++;
return( TRUE );
}
// ************************************************************************
// FUNCTION : AddToolLabel( HANDLE hInst, INT iId, LPTSTR szLabel, INT iWidth, DWORD dwStyle )
// PURPOSE :
// COMMENTS :
// ************************************************************************
HWND
AddToolLabel( HANDLE hInstance, INT iId, LPTSTR szLabel, INT iWidth, DWORD dwStyle )
{
HDC hdc;
if( cntToolCtrls >= MAXCTRLS )
return( (HWND) 0 ); // No room left in our fixed array
toolCtrl[cntToolCtrls].hwnd = CreateWindow ( TEXT( "STATIC" ), szLabel,
WS_CHILD //| WS_CLIPSIBLINGS
| WS_VISIBLE | dwStyle,
0, 0, 0, 0,
hwndTools, (HMENU)iId, hInstance, NULL );
if( !toolCtrl[cntToolCtrls].hwnd )
return( (HWND) 0 ); // CreateWindow failed for some reason
// SendMessage (toolCtrl[cntToolCtrls].hwnd, WM_SETFONT, (UINT) hfontTools, MAKELONG (TRUE, 0) );
toolCtrl[cntToolCtrls].wType = TC_LABEL;
hdc = GetDC (hwndTools);
if( iWidth < 0 ) {
toolCtrl[cntToolCtrls].iWidth = tmToolFont.tmAveCharWidth * abs(iWidth);
}
else if( iWidth == 0 ) {
#ifdef WIN32
SIZE size;
GetTextExtentPoint( hdc, szLabel, lstrlen(szLabel), &size );
toolCtrl[cntToolCtrls].iWidth = size.cx;
#else
toolCtrl[cntToolCtrls].iWidth = LOWORD( GetTextExtent( hdc, szLabel, lstrlen(szLabel) ) );
#endif
}
else {
toolCtrl[cntToolCtrls].iWidth = iWidth;
}
toolCtrl[cntToolCtrls].iHeight = tmToolFont.tmHeight;
if( (toolCtrl[cntToolCtrls].iHeight + (6*cyToolBorder)) > dyTools ) {
dyTools = (toolCtrl[cntToolCtrls].iHeight + (6*cyToolBorder));
}
ReleaseDC( hwndTools, hdc );
UpdatePositions( NULL );
return( toolCtrl[cntToolCtrls++].hwnd );
}
// ************************************************************************
// FUNCTION : AddToolCombo (HANDLE hInst, INT iId, INT iWidth, DWORD dwStyle)
// PURPOSE :
// COMMENTS :
// ************************************************************************
HWND
AddToolCombo (HANDLE hInstance, INT iId, INT iWidth, DWORD dwStyle)
{
if( cntToolCtrls >= MAXCTRLS )
return( (HWND) 0 ); // No room left in our fixed array
if( dwStyle==0 )
dwStyle = CBS_DROPDOWNLIST;
toolCtrl[cntToolCtrls].hwnd = CreateWindow ( TEXT( "COMBOBOX" ), TEXT( "" ),
WS_CHILD | // WS_CLIPSIBLINGS |
WS_VISIBLE | dwStyle,
0, 0, 0, 0,
hwndTools, (HMENU) iId, hInstance, NULL );
if( !toolCtrl[cntToolCtrls].hwnd )
return( (HWND) 0 ); // CreateWindow failed for some reason
// SendMessage (toolCtrl[cntToolCtrls].hwnd, WM_SETFONT, (UINT)hfontTools, MAKELONG (TRUE, 0));
toolCtrl[cntToolCtrls].wType = TC_COMBO;
if( iWidth < 0 ) {
toolCtrl[cntToolCtrls].iWidth = tmToolFont.tmAveCharWidth * abs(iWidth);
}
else if( iWidth == 0 ) {
toolCtrl[cntToolCtrls].iWidth = tmToolFont.tmAveCharWidth * 15; // just a default width
}
else {
toolCtrl[cntToolCtrls].iWidth = iWidth;
}
toolCtrl[cntToolCtrls].iHeight = dyCombo;
if( (toolCtrl[cntToolCtrls].iHeight + (6*cyToolBorder)) > dyTools ) {
dyTools = (toolCtrl[cntToolCtrls].iHeight + (6*cyToolBorder));
}
UpdatePositions( NULL );
return( toolCtrl[cntToolCtrls++].hwnd );
}
// ************************************************************************
// FUNCTION : AddToolButton( HANDLE hInst, INT iId, LPTSTR szLabel, INT iWidth, INT iHeight, DWORD dwStyle )
// PURPOSE :
// COMMENTS :
// ************************************************************************
HWND
AddToolButton( HANDLE hInstance, INT iId, LPTSTR szLabel, INT iWidth, INT iHeight, DWORD dwStyle )
{
HDC hdc;
if( cntToolCtrls >= MAXCTRLS )
return( (HWND) 0 ); // No room left in our fixed array
if( dwStyle == 0 )
dwStyle = BS_PUSHBUTTON | BS_OWNERDRAW;
toolCtrl[cntToolCtrls].hwnd = CreateWindow ( TEXT( "BUTTON" ), szLabel,
WS_CHILD | // WS_CLIPSIBLINGS |
WS_VISIBLE | dwStyle,
0, 0, 0, 0,
hwndTools, (HMENU)iId, hInstance, NULL );
if( !toolCtrl[cntToolCtrls].hwnd )
return( (HWND) 0 ); // CreateWindow failed for some reason
// SendMessage (toolCtrl[cntToolCtrls].hwnd, WM_SETFONT, (UINT)hfontTools, MAKELONG (TRUE, 0));
toolCtrl[cntToolCtrls].wType = TC_BUTTON;
hdc = GetDC (hwndTools);
SelectObject (hdc, hfontTools);
if( iWidth < 0 ) {
toolCtrl[cntToolCtrls].iWidth = tmToolFont.tmAveCharWidth * abs(iWidth);
toolCtrl[cntToolCtrls].iWidth += (6*cxToolBorder);
}
else if( iWidth == 0 ) {
#ifdef WIN32
SIZE size;
GetTextExtentPoint (hdc, szLabel, lstrlen(szLabel), &size);
toolCtrl[cntToolCtrls].iWidth = size.cx;
#else
toolCtrl[cntToolCtrls].iWidth = LOWORD(GetTextExtent (hdc, szLabel, lstrlen(szLabel)));
#endif
toolCtrl[cntToolCtrls].iWidth += (6*cxToolBorder);
}
else {
toolCtrl[cntToolCtrls].iWidth = iWidth;
}
if( iHeight < 0 ) {
toolCtrl[cntToolCtrls].iHeight = tmToolFont.tmHeight;
toolCtrl[cntToolCtrls].iHeight += (6*cyToolBorder);
}
else if( iHeight==0 ) {
toolCtrl[cntToolCtrls].iHeight = dyTools - (6*cyToolBorder);
} else {
toolCtrl[cntToolCtrls].iHeight = iHeight;
}
if( (toolCtrl[cntToolCtrls].iHeight + (6*cyToolBorder)) > dyTools ) {
dyTools = (toolCtrl[cntToolCtrls].iHeight + (6*cyToolBorder));
}
if( dwStyle & BS_OWNERDRAW ) {
toolCtrl[cntToolCtrls].hIcon = LoadIcon (hInstance, szLabel);
}
else {
toolCtrl[cntToolCtrls].hIcon = NULL;
}
ReleaseDC( hwndTools, hdc );
UpdatePositions( NULL );
return toolCtrl[cntToolCtrls++].hwnd;
}
// ************************************************************************
// FUNCTION : DestroyToolBar (VOID)
// PURPOSE :
// COMMENTS :
// ************************************************************************
BOOL
DestroyToolBar( VOID )
{
return( DeleteObject(hbrBtnFace) );
}
// ************************************************************************
// FUNCTION : DrawButton (HDC hdc, RECT rect, BOOL bDown, HICON hIcon)
// PURPOSE :
// COMMENTS :
// ************************************************************************
VOID
DrawButton (HDC hdc, RECT rect, BOOL bDown, HICON hIcon)
{
HBRUSH hBrush, hbrFrame, hbrBtnFace, hbrHilite, hbrShadow;
RECT border;
INT i;
hbrFrame = CreateSolidBrush( rgbFrame );
hbrBtnFace = CreateSolidBrush( rgbBtnFace );
hbrHilite = CreateSolidBrush( rgbHilite );
hbrShadow = CreateSolidBrush( rgbShadow );
FillRect (hdc, &rect, hbrBtnFace);
if( hIcon ) {
if( bDown ) {
DrawIcon (hdc, rect.left + (4*cyToolBorder), rect.top + (4*cyToolBorder), hIcon);
}
else {
DrawIcon (hdc, rect.left + (3*cyToolBorder), rect.top + (3*cyToolBorder), hIcon);
}
}
hBrush = hbrFrame;
border = rect; border.bottom = border.top + cyToolBorder;
FillRect( hdc, &border, hBrush );
border = rect; border.right = border.left + cxToolBorder;
FillRect( hdc, &border, hBrush );
border = rect; border.top = border.bottom - cyToolBorder;
FillRect( hdc, &border, hBrush );
border = rect; border.left = border.right - cxToolBorder;
FillRect( hdc, &border, hBrush );
for( i= 0; i<2; i++ ) {
InflateRect( &rect, -cxToolBorder, -cyToolBorder );
hBrush = ( bDown? hbrShadow:hbrHilite );
border = rect; border.bottom = border.top + cyToolBorder;
FillRect( hdc, &border, hBrush );
border = rect; border.right = border.left + cxToolBorder;
FillRect( hdc, &border, hBrush );
if( !bDown ) {
hBrush = hbrShadow;
border = rect; border.top = border.bottom - cyToolBorder;
FillRect( hdc, &border, hBrush );
border = rect; border.left = border.right - cxToolBorder;
FillRect( hdc, &border, hBrush );
}
}
DeleteObject( hbrFrame );
DeleteObject( hbrBtnFace );
DeleteObject( hbrHilite );
DeleteObject( hbrShadow );
}
// ************************************************************************
// FUNCTION : ToolsProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
// PURPOSE :
// COMMENTS :
// ************************************************************************
LONG CALLBACK
ToolsProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
INT iType, idCtrl, msgCtrl, i;
RECT rect, border;
COLORREF clrColor = rgbToolBar;
HWND hwndCtl;
LONG lStyle;
HBRUSH hBrush = hbrToolBar;
LPDRAWITEMSTRUCT lpdi;
HICON hIcon;
switch( msg ) {
case WM_CREATE:
//DebugOut( "[ToolsProc] WM_CREATE" );
#ifdef NOCREATEFONT // CreateFont is failing in NT
hfontTools = (HFONT)NULL;
#else
hfontTools = CreateFont(16, 0, 0, 0, 0, 0, 0, 0,
ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, NULL);
if( !hfontTools ) {
MessageBox( GetFocus(), TEXT( "Failed To Create Font" ),
TEXT( "StatusProc" ), MB_OK );
}
#endif
hdc = GetDC( hwnd );
SelectObject( hdc, hfontTools );
GetTextMetrics( hdc, &tmToolFont );
ReleaseDC( hwnd, hdc );
//DebugOut( "[ToolsProc] WM_CREATE (exit)" );
return( DefWindowProc( hwnd, msg, wParam, lParam ) );
case WM_SIZE:
UpdatePositions(hwnd);
break;
#ifdef WIN32
case WM_CTLCOLORLISTBOX:
case WM_CTLCOLOREDIT:
case WM_CTLCOLORSTATIC:
case WM_CTLCOLORBTN:
case WM_CTLCOLORDLG:
case WM_CTLCOLORMSGBOX:
case WM_CTLCOLORSCROLLBAR:
iType = msg - WM_CTLCOLORMSGBOX;
hdc = (HDC)wParam;
hwndCtl = (HWND)lParam;
#else
case WM_CTLCOLOR:
hdc = wParam;
hwndCtl = LOWORD( lParam );
iType = HIWORD ( lParam );
#endif
switch (iType) {
case CTLCOLOR_EDIT: //Edit control
clrColor = rgbBtnFace;
hBrush = hbrToolBar;
break;
case CTLCOLOR_LISTBOX: //List-box control
lStyle = GetWindowLong (hwndCtl, GWL_STYLE);
if( lStyle & CBS_SIMPLE ) {
clrColor = rgbToolBar;
hBrush = hbrToolBar;
}
else {
clrColor = rgbBtnFace;
hBrush = hbrToolBar;
}
break;
case CTLCOLOR_STATIC:
clrColor = rgbBtnFace;
hBrush = hbrBtnFace;
break;
case CTLCOLOR_BTN:
clrColor = rgbBtnFace;
hBrush = hbrBtnFace;
break;
case CTLCOLOR_SCROLLBAR:
case CTLCOLOR_DLG:
case CTLCOLOR_MSGBOX:
default:
return FALSE;
}
SetBkColor(hdc, clrColor);
return (LONG)hBrush;
case WM_PAINT:
hdc = BeginPaint (hwnd, &ps);
GetClientRect (hwnd, &rect);
/* Shade the top of the bar white */
hBrush = CreateSolidBrush( rgbDirectLight );
border = rect;
border.bottom = border.top + cyToolBorder;
FillRect (hdc, &border, hBrush);
DeleteObject (hBrush);
/* Shade the bottom of the bar dark gray */
hBrush = CreateSolidBrush( rgbShadow );
border = rect;
border.top = border.bottom - cyToolBorder;
FillRect (hdc, &border, hBrush);
DeleteObject (hBrush);
EndPaint (hwnd, &ps);
return DefWindowProc (hwnd, msg, wParam, lParam);
case WM_DRAWITEM: // Indicates that an owner-draw control needs to be redrawn.
lpdi = (LPDRAWITEMSTRUCT)lParam;
switch( lpdi->itemAction ) {
// handle normal drawing of button, but check if its selected or focus
case ODA_SELECT:
case ODA_DRAWENTIRE:
// handle button pressed down select state -- button down bitmap
// text is right & down 2 pixels
hIcon = NULL;
for( i=0; i< cntToolCtrls; i++ ) {
if( toolCtrl[i].hwnd == lpdi->hwndItem ) {
hIcon = toolCtrl[i].hIcon;
}
}
if( lpdi->itemState & ODS_SELECTED ) {
DrawButton( lpdi->hDC,lpdi->rcItem, TRUE, hIcon );
}
else { // not selected -- button up; text is in normal position
DrawButton( lpdi->hDC,lpdi->rcItem, FALSE, hIcon );
}
return( TRUE );
}
break;
case WM_COMMAND:
#ifdef WIN32
idCtrl = LOWORD( wParam );
msgCtrl = HIWORD( wParam );
hwndCtl = (HWND) lParam;
#else
idCtrl = wParam;
msgCtrl = HIWORD( lParam );
hwndCtl = LOWORD( lParam );
#endif
if( GetWindowLong( hwndCtl, GWL_STYLE ) & BS_OWNERDRAW ) {
if( msgCtrl == BN_DOUBLECLICKED ) {
PostMessage( hwndCtl, WM_LBUTTONDOWN, 0, 0 );
return( TRUE );
}
}
PostMessage (hwndMain, msg, wParam, lParam);
return DefWindowProc (hwnd, msg, wParam, lParam);
default:
return( DefWindowProc( hwnd, msg, wParam, lParam ) );
}
return( 0L );
}
// ========================================================================
// STATUS BAR FUNCTIONS
// ========================================================================
// ************************************************************************
// FUNCTION :
// PURPOSE :
// COMMENTS :
// ************************************************************************
BOOL
InitStatusBar( HANDLE hInstance )
{
WNDCLASS wndclass;
hbrStatus = CreateSolidBrush( rgbBtnFace );
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = (WNDPROC)StatusProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = NULL;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
wndclass.hbrBackground = hbrStatus;
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = TEXT( "SamplerStatus" );
if( !RegisterClass(&wndclass) )
return( FALSE );
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = (WNDPROC)StatusFieldProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = NULL;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
wndclass.hbrBackground = hbrStatus;
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = TEXT( "StatusField" );
if( !RegisterClass (&wndclass) )
return( FALSE );
}
// ************************************************************************
// FUNCTION :
// PURPOSE :
// COMMENTS :
// ************************************************************************
BOOL
CreateStatusBar (HWND hwnd, HANDLE hInstance, INT iId)
{
cxStatusBorder = GetSystemMetrics (SM_CXBORDER);
cyStatusBorder = GetSystemMetrics (SM_CYBORDER);
//DebugOut( ": Calling CreateWindow" );
hwndStatus = CreateWindow ( TEXT( "SamplerStatus" ), TEXT( "SamplerStatus" ),
WS_CHILD //| WS_CLIPSIBLINGS
| WS_BORDER | WS_VISIBLE,
0, 0, 0, 0,
hwnd, (HMENU)iId, hInstance, NULL);
if (!hwndStatus) {
return FALSE;
}
//DebugOut( "CreateWindow Succeeded" );
return TRUE;
}
// ************************************************************************
// FUNCTION :
// PURPOSE :
// COMMENTS :
// ************************************************************************
int
StatusBarHeight (HWND hwnd)
{
RECT rect;
GetClientRect( hwndStatus, &rect );
return rect.bottom-rect.top;
hwnd; // unreferenced
}
// ************************************************************************
// FUNCTION :
// PURPOSE :
// COMMENTS :
// ************************************************************************
BOOL
AdjustStatusBar (HWND hwnd)
{
RECT rect;
GetClientRect (hwnd, &rect);
MoveWindow (hwndStatus,
rect.left-cxStatusBorder,
rect.bottom - dyStatus + cyStatusBorder,
rect.right - rect.left + (cxStatusBorder*2),
dyStatus, TRUE);
return TRUE;
}
// ************************************************************************
// FUNCTION :
// PURPOSE :
// COMMENTS :
// ************************************************************************
HWND
AddStatusField (HANDLE hInstance, INT iId, INT iMin, INT iMax, BOOL bNewGroup)
{
LONG lStyle;
if( cntStatusField >= MAXSTATUS )
return( (HWND) 0 ); // No room left in our fixed array
statusField[cntStatusField].hwnd = CreateWindow( TEXT( "StatusField" ), TEXT( "" ),
WS_CHILD | WS_VISIBLE,
0, 0, 0, 0,
hwndStatus, (HMENU)iId,
hInstance, NULL );
if( !statusField[cntStatusField].hwnd )
return( (HWND) 0 ); // CreateWindow failed for some reason
if( iMin < 0 ) {
statusField[cntStatusField].iMinWidth = tmStatusFont.tmAveCharWidth*abs(iMin);
}
else {
statusField[cntStatusField].iMinWidth = iMin;
}
if( iMax < 0 ) {
statusField[cntStatusField].iMaxWidth = tmStatusFont.tmAveCharWidth*abs(iMax);
}
else {
statusField[cntStatusField].iMaxWidth = iMax;
}
if( bNewGroup ) {
lStyle = GetWindowLong( statusField[cntStatusField].hwnd, GWL_STYLE );
lStyle |= WS_GROUP;
SetWindowLong( statusField[cntStatusField].hwnd, GWL_STYLE, lStyle );
}
return( statusField[cntStatusField++].hwnd );
}
// ************************************************************************
// FUNCTION :
// PURPOSE :
// COMMENTS :
// ************************************************************************
BOOL
DestroyStatusBar (VOID)
{
return( DeleteObject( hbrStatus ) );
}
// ************************************************************************
// FUNCTION :
// PURPOSE :
// COMMENTS :
// ************************************************************************
LONG CALLBACK
StatusProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
INT x, y, i;
INT wAvailWidth, wFlexWidth, cntFlexWidth, wNeedWidth, cntNeedWidth;
RECT rect, border;
HBRUSH hBrush;
switch (msg) {
case WM_CREATE:
#ifdef NOCREATEFONT // CreateFont is failing in NT
hfontStatus = (HFONT)NULL;
#else
hfontStatus = CreateFont(16, 0, 0, 0, 0, 0, 0, 0,
ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, NULL);
if( !hfontStatus ) {
MessageBox( GetFocus(), TEXT( "Failed To Create Font" ),
TEXT( "StatusProc" ), MB_OK );
}
#endif
hdc = GetDC (hwnd);
SelectObject (hdc, hfontStatus);
GetTextMetrics (hdc, &tmStatusFont);
cxStatusBorder = GetSystemMetrics (SM_CXBORDER);
cyStatusBorder = GetSystemMetrics (SM_CYBORDER);
cxFrame = 3*cxStatusBorder;
cyFrame = 3*cyStatusBorder;
dyField = tmStatusFont.tmHeight + (2*cyStatusBorder);
dyStatus = dyField + (2*cyFrame);
ReleaseDC (hwnd, hdc);
return DefWindowProc (hwnd, msg, wParam, lParam);
case WM_SIZE:
if( cntStatusField ) {
GetClientRect (hwnd, &rect);
wAvailWidth = rect.right - rect.left - (cxStatusBorder*8);
wNeedWidth = 0;
cntNeedWidth = 0;
cntFlexWidth = 0;
/* First Pass: Dole out to fields that have a minimum need */
for (i=0; i<cntStatusField; i++) {
statusField[i].iGiveWidth = 0; // Make sure all are initialized to 0
if( statusField[i].iMinWidth ) {
/* (n, ?) */
statusField[i].iGiveWidth = statusField[i].iMinWidth;
wAvailWidth -= (statusField[i].iGiveWidth + cxStatusBorder*2);
if( GetWindowLong(statusField[i].hwnd, GWL_STYLE) & WS_GROUP ) {
wAvailWidth -= cxStatusBorder*4;
}
}
else {
/* They didn't specify a minimum... don't give them anything yet */
/* (0, ?) */
statusField[i].iGiveWidth = 0;
//++cntFlexWidth;
}
/* For those that have a minimum, but can grow to be as large as possible...*/
/* (n, 0) */
if( (statusField[i].iMinWidth >0) && (statusField[i].iMaxWidth ==0) ) {
++cntFlexWidth;
}
/* For those that have a max that is greater then their min... */
/* Includes (0,n) and (n,>n) */
if( statusField[i].iMaxWidth > statusField[i].iGiveWidth ) {
wNeedWidth += (statusField[i].iMaxWidth - statusField[i].iGiveWidth);
++cntNeedWidth;
}
}
/* Second Pass: Dole out to fields that have a stated maximum need */
/* This will also hit those who had no minimum, but did have a maximum */
/* It will still not give anything to those with no min, no max */
if( (cntNeedWidth > 0) && (wAvailWidth > 0) ) {
if( wNeedWidth > wAvailWidth ) {
wNeedWidth = wAvailWidth;
}
wNeedWidth = wNeedWidth / cntNeedWidth;
for( i=0; i<cntStatusField; i++ ) {
if( statusField[i].iMaxWidth > statusField[i].iGiveWidth ) {
statusField[i].iGiveWidth += wNeedWidth;
wAvailWidth -= (statusField[i].iGiveWidth + cxStatusBorder*2);
if( GetWindowLong(statusField[i].hwnd, GWL_STYLE) & WS_GROUP ) {
wAvailWidth -= cxStatusBorder*4;
}
}
}
}
/* Third Pass: Dole out the remaining to fields that want all they can get */
/* This includes those who had a minimum, but no maximum */
if( (cntFlexWidth > 0) && (wAvailWidth > 0) ) {
wFlexWidth = wAvailWidth / cntFlexWidth;
for( i=0; i<cntStatusField; i++ ) {
if( statusField[i].iMaxWidth==0 ) {
statusField[i].iGiveWidth += wFlexWidth;
wAvailWidth -= ((wFlexWidth - statusField[i].iMinWidth) + cxStatusBorder*2);
if( GetWindowLong(statusField[i].hwnd, GWL_STYLE) & WS_GROUP ) {
wAvailWidth -= cxStatusBorder*4;
}
}
}
}
x = cxStatusBorder*4;
y = rect.top + (2*cyStatusBorder);
for( i=0; i<cntStatusField; i++ ) {
if( GetWindowLong (statusField[i].hwnd, GWL_STYLE) & WS_GROUP ) {
x += (cxStatusBorder*4);
}
MoveWindow( statusField[i].hwnd, x, y, statusField[i].iGiveWidth, dyField, TRUE );
x += statusField[i].iGiveWidth + (cxStatusBorder*2);
}
}
break;
case WM_PAINT:
hdc = BeginPaint( hwnd, &ps );
GetClientRect( hwnd, &rect );
hBrush = CreateSolidBrush( rgbToolBar );
border = rect;
border.bottom = border.top + cyStatusBorder;
FillRect( hdc, &border, hBrush );
DeleteObject (hBrush);
hBrush = CreateSolidBrush( rgbShadow );
border = rect;
border.top = border.bottom - cyStatusBorder;
FillRect( hdc, &border, hBrush );
DeleteObject( hBrush );
EndPaint( hwnd, &ps );
return( DefWindowProc (hwnd, msg, wParam, lParam) );
default:
return( DefWindowProc( hwnd, msg, wParam, lParam ) );
}
return( 0L );
}
// ************************************************************************
// FUNCTION :
// PURPOSE :
// COMMENTS :
// ************************************************************************
LONG CALLBACK
StatusFieldProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static HFONT hFieldFont;
HDC hdc;
PAINTSTRUCT ps;
RECT rect, border;
HBRUSH hBrush;
WORD edge = 1;
HFONT hTmp;
TCHAR szText[80];
INT len;
switch( msg ) {
case WM_CREATE:
hFieldFont = CreateFont( 8, 0, 0, 0, 0, 0, 0, 0,
ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, TEXT( "Helv" ) );
return( DefWindowProc( hwnd, msg, wParam, lParam ) );
case WM_PAINT:
hdc = BeginPaint( hwnd, &ps );
GetClientRect( hwnd, &rect );
//-- fill top of the status windows
hBrush = CreateSolidBrush( rgbShadow );
border = rect;
border.bottom = border.top + cyStatusBorder;
FillRect( hdc, &border, hBrush );
border = rect;
border.right = border.left + cxStatusBorder;
FillRect( hdc, &border, hBrush );
DeleteObject( hBrush );
//-- fill botton of the status windows
hBrush = CreateSolidBrush( rgbDirectLight );
border = rect;
border.top = border.bottom - cyStatusBorder;
FillRect( hdc, &border, hBrush );
border = rect;
border.left = border.right - cxStatusBorder;
FillRect( hdc, &border, hBrush );
DeleteObject( hBrush );
if( len = GetWindowText( hwnd, szText, sizeof (szText) ) ) {
hTmp = SelectObject( hdc, hfontStatus );
SetTextColor( hdc, rgbStatic );
SetBkColor( hdc, rgbToolBar );
InflateRect( &rect, -(cxStatusBorder*2), -cyStatusBorder );
ExtTextOut( hdc, rect.left, rect.top,
ETO_OPAQUE | ETO_CLIPPED,
&rect,
(LPTSTR) szText,
len, NULL);
SelectObject( hdc, hTmp );
}
EndPaint( hwnd, &ps );
break;
case WM_SETTEXT:
InvalidateRect( hwnd, NULL, TRUE );
return( DefWindowProc( hwnd, msg, wParam, lParam ) );
default:
return( DefWindowProc( hwnd, msg, wParam, lParam ) );
}
return( 0L );
}